home *** CD-ROM | disk | FTP | other *** search
- Path: telepost.no!usenet
- From: Carsten Arnholm <ca@sesam.dnv.no>
- Newsgroups: comp.lang.fortran,comp.lang.c++
- Subject: Re: How to link Fortran with c++ ??
- Date: 31 Jan 1996 14:42:57 GMT
- Organization: DNV
- Message-ID: <4env5h$3ai@nms.telepost.no>
- References: <310DD74F.59E2@imacsg1.epfl.ch>
- NNTP-Posting-Host: hugin.sesam.dnv.no
- Mime-Version: 1.0
- Content-Type: text/plain; charset=us-ascii
- Content-Transfer-Encoding: 7bit
- X-Mailer: Mozilla 1.1 (Windows; I; 32bit)
-
- Niels Hilbrink <Niels@imacsg1.epfl.ch> wrote:
- >Hi,
- >
- >I have to link a piece of fortran code with c++ code but since if never
- >done that before I'd like to know a) can it be done and b) is it
- >difficult.
- >
- >Everything concerning this subject is welcome.
- >
- >Gr.
- >Niels Hiblrink
- >
- >
- >--
- >
- > The most overlooked advantage to owning a computer is
- > that if they foul up there's no law against wacking
- > them around a little.
- >
- >------------------------------------------------------------
- >Koen D'Hondt Niels Hilbrink
- >koen@@dutlhs1.lr.tudelft.nl niels@dutlcc3.lr.tudelft.nl
- >
- >**** Ripley Software Development ****
- >(finger niels@dutlcc3.lr.tudelft.nl for more information.)
- >------------------------------------------------------------
-
- Hi there,
-
-
- Mixed language programming (C++/FORTRAN 77) is not as hard as
- it may seem.
-
- The only non-trivial problem you must solve is fortran CHARACTERs.
- You need to write a minimal CHARACTER class in C++.
-
- If you require single-source portability, it becomes slightly
- more complicated, but not impossible.
-
- Below follows a summary of some stuff that I have done, plus
- some additional thoughts.
-
-
-
- typedef int INTEGER;
- typedef float REAL;
- typedef int LOGICAL;
-
- #include "character.h" // CHARACTER class (see below)
-
- #define SUBROUTINE extern "C" void __stdcall
- #define INTEGER_FUNCTION extern "C" INTEGER __stdcall
- #define REAL_FUNCTION extern "C" REAL __stdcall
-
-
-
- The CHARACTER class may look something like this:
-
-
-
- #include <string.h>
-
- /*
- class CHARACTER
- ===============
- A minimal class used when passing C-string arguments from C++ to
- FORTRAN 77 (received as FORTRAN 77 CHARACTER strings), and subsequently
- returned back to C++ as properly zero terminated c-strings.
-
- Method used for zero-termination:
- =================================
- When the CHARACTER destructor is activated (typically when the
- CHARACTER object goes out of scope within a C++ stub function)
- the zero-termination of the c-string is automatically managed.
-
- FORTRAN Assumptions:
- ====================
- (1) FORTRAN truncates assigned strings when CHARACTER variable is too short
- (2) FORTRAN pads CHARACTER variable with blanks when assigned string is short
- (3) FORTRAN represents a CHARACTER as a string pointer followed by a length
-
- Author: Carsten A. Arnholm, 20-AUG-1995
- */
-
- class CHARACTER {
- public:
- CHARACTER(char* cstring) : rep(cstring), len(strlen(cstring)) {};
- CHARACTER(char* cstring, const size_t lstr);
- ~CHARACTER();
- public:
- char* rep; // Actual string
- size_t len; // String length, used by FORTRAN intrinsic function LEN()
- };
-
- inline CHARACTER::CHARACTER(char* cstring, const size_t lstr) : rep(cstring), len(lstr-1)
- {
- size_t actual = strlen(rep);
- for(size_t i=actual;i<len;i++) rep[i]=' ';
- rep[len]='\0';
- }
-
- inline CHARACTER::~CHARACTER() {
- for(size_t i=strlen(rep)-1;i>=0;i--) {
- if(rep[i] != ' ') {
- rep[i+1] = '\0';
- break;
- }
- }
- }
-
-
- now you can declare FORTRAN subroutine prototypes in C++:
-
- SUBROUTINE MYSUB(INTEGER& I1, CHARACTER C1, INTEGER& I2);
-
- To create a portable solution, do the following:
-
- a) Write header files for your FORTRAN libraries as shown above.
- b) Compile FORTRAN code and create *.lib files.
- c) Include the FORTRAN library header files in your C++ code.
- d) Call FORTRAN according to above prototype example.
- e) Compile C++ code and link with FORTRAN libraries
- f) This executes directly for Visual C++ 2.1 & 4.0 in combination
- With Fortran Powerstation
-
- porting to other machines:
-
- a) Leave C++ and Fortran code untouched (single source requirement!)
- b) Write a small C++ program that read your FORTRAN library header files,
- and generate:
- b.1: a platform-specific header file for the fortran
- library. Here you deal with upper/lowercase names,
- trailing underscores, character lengths etc.
- b.2: a platform-specific *.CPP file containing inline
- functions that convert from
- MYSUB(INTEGER& I1, CHARACTER C1, INTEGER& I2)
- to
- mysub_(int& I1, char* C1.rep, int& I2, int C1.len)
-
- (example above is for for SGI)
- c) Compile & link this generated code with your application.
- e) Should execute on basically any platform (UNIX, VMS, ...)
-
-
- Other issues
- ============
-
- a) Calling/linkage convention (C++).
- This is taken care of through the use of the statement: extern "C"
- This avoids name mangling which is not used in FORTRAN.
-
- b) Routine names
- An ANSI standard FORTRAN routine name should be defined in UPPERCASE
- and max 6 characters. This does not, however, mean that the name
- used when calling from C/C++ should be in uppercase. On the SGI machine
- (i.e. unix) the routine must be in lowercase with a trailing underscore.
- On other unix boxes, you may need a leading underscore and/or uppercase
- name.
-
- Example:
- FORTRAN : SUBROUTINE MYSUB
- Machine-dependent C++ prototype (SGI): extern "C" void mysub_();
-
- c) Parameter types and argument passing
- FORTRAN will always require parameters to be passed by reference
-
- FORTRAN : SUBROUTINE MYSUB(IVAL)
- INTEGER IVAL
-
- Machine-dependent C++ prototype (SGI): extern "C" void mysub_(int& IVAL);
-
-
- d) Machine dependent comparison of language types:
-
- FORTRAN C++
- ======= ===
- INTEGER int&
- REAL float&
- LOGICAL int&
- CHARACTER char* (+ size_t length )
- DOUBLE PRECISION double&
-
- good luck,
-
- Carsten Arnholm
- ca@sesam.dnv.no
-
-
-
-
-